% =========================================================================
%% 
% COMPARE_IRF
%
% Simple version to compare IRFs of the LMJ project. 
% Allows for: 
% 1) Single mode and a perturbation of a single parameter, given user
% defined values 
%
% 2) Multiple modes 
% 
% 3) Single mode with no perturbation 
%
% If loading a single mode, then must provide a paremeter name and a range
% of values to perturb it. If left empty it will compute a single set of
% IRFS. 
%
%% Documentation User Defined Settings 
% 
%% A. File and model settings 
% 
% *LOADPATH:* Subfolder within this path from where will pick up XLS file
% with the mode or modes. E.g. 'Gnp\L2YChi1Gtv\dtrsep2010\09 13 10'
% 
% *OUTPATH_NAME:* Name of the output path, which will be a subfolder of
% LOADPATH.  E.g. 'T2d Perturb'
%
% *FNAME:* name of the XLS file (extension not needed). E.g. 'Modes'. 
%
% *LEGENDS:*, name of the different modes to be loaded (applies only to
% multiple modes), leave empty if loading a single mode. E.g. {'Mode
% 1','Mode 2'}; 
%
% *SHEETNAME:*, (optional), sheet name. Leave empty if using a single sheet XLS
% file, specify otherwise. 
%
% *FUNCMOD:*, function handle of which model to use for the solution, e.g.
% @MODGNPL2Y or @MODGNPL2YCHI1.  
%
%% B. Settings for the IRFS 
% 
% *IRF_REPORT:* cell with the name of the state series that will be reported
% in the IRF. See STANAMES within the model code. 
% *NOTE:* in order to obtain an IRF for the level of a series
% written as a growth rate in the code type its name following by lev, in a single cell. 
% E.g. for series 'yobs' (observable output) choosing 'yobs lev' will automatically do a cumsum of the IRFS. 
% 
% *IRF_SHOCKS:* cell with the name of the shocks for which to report 
% the IRFS. If left empty, all shocks will be reported. E.g. ={'Neutral
% sta','MEI sta'}; 
%
% *IRF_REPORT_GNAMES* (optional) cell with alternative names wish to use for the
%  graphs for the states defined in *IRF_REPORT*. Both must be of the same length.
%  E.g. if IRF_REPORT={'yobs lev',u'}, could have
%  IRF_REPORT_GNAMES={'Output','Unemployment'}, and the latter will be used in
%  the graphs. 
%
% *NIRFPER:* scalar with the number of periods for which to plot the IRFS.
% E.g. 24. 
%
%% C. Settings for single parameter perturbations 
%
% Note: if single mode loaded and *PERTURB_NAME* empty, [], then only IRFS to the
% mode will be computed. 
%
%
% These inputs apply only to the case in which a single parameter is
% loaded and one of its elements will be perturbed. If these are defined
% and a multiple parameter spreadsheet is loaded, then these settings are
% irrelevant, but will cause no error message. 
%
% *PERTURB_NAME*, string or cell with the name of the parameter that will be perturbed 
% E.g. 'T2d'. 
%
% *PERTURB_GRID*, vector with parameter values for the parameter specified
% in PERTURB_NAME. *Note:* the value of the mode will be included in the grid
% by default. Values will be sorted in ascending order, including the mode.
% E.g. =[7,20]; 
% 
%% D. Additional settings for the plots 
% 
% The following give great control over how the multiple IRFS will be
% plotted. If not defined or left empty, default values are assigned. 
% *See COMPARE_IRF_PLOTS.m* for details. 
%
% *IN.TITFONT:*Size of title  fonts 
%
% *IN.LEGFONT:* Size of legend fonts
%
% *IN.FLAG_ADDPATH:*, if ==1 will create a cover sheet with the path where the IRFS
% stored. 
%
% *IN.ADDCOVER:*, Cell (as large as 4x1) with text to put on the cover
% sheet 
% 
% *IN.FLAG_LEGENDOFF:* ==1, no legend will be produced, otherwise the
%    cell in *legends* will be put at the bottom of the graph
%
% 
%%  Notes
% Created Sep 13 2010 
%
% Alejandro Justiniano 
%
% Modifications: 
%% Settings to allow for graphs for paper/presentations Sep 17 2010 
%
% 1) If single mode loaded and *PERTURB_NAME* empty, [], then only IRFS to the
%    mode will be computed. 
%
% 2) If *IN.FLAG_LEGENDOFF=1* No legend will be produced, otherwise the
%    string in *legends* will be put at the bottom of the graph 
%
% 3) *IRF_REPORT_GNAMES* (optional) cell with alternative names wish to use for the
%    graphs for the states defined in *IRF_REPORT*. Both must be of the same length. 
%    E.g. if IRF_REPORT={'yobs lev',u'}, could have
%    IRF_REPORT_NAMES={'Output','Unemployment'}, and the latter will be used in
%    the graphs. 

%
%% For Claudio
%
%% Code names These are the names of the main codes currently at use 
%
% *1) mod   Gnp  L2Y       Gtv* 
%
% *2) mod   Gnp  L2Y Chi1   Gtv* 
%
% L2Y :  parameter is directly on L2Y100, RBAR is implicit 
% Chi1:  Chi==1, first code, Chi > 1 
% Gtv :  The G solution matrix is time varying, since all variables are
% monthly and use the cummulator representation for the mixed frequency
% estimation. 
%
%% Main files
% 
% The current prior for botjh model is *dtrsep2010 Sh'. 
% 
% The name of the main output folders are as follows: 
% 
% For *modGnpL2YGtv* 
%
% *\Gnp\L2YGtv\dtrsep2010\09 10 10:* this is the long-run over the
% weekend. See tab_loop.xls and complete output there. 
% The refined run of that is *Gnp\L2YGtv\dtrsep2010\09 13 10*. See
% *tab_loop.xls*. The 3 modes from this run are stored in *modesSep13.xls*.
% 
% 
% For *modGnpL2YChi1Gtv:* 
%
% *Gnp\L2YChi1Gtv\dtrsep2010\09 10 10:* this is the long-run over the
% weekend. See tab_loop.xls The refined run of that is
% *Gnp\L2YChi1Gtv\dtrsep2010\09 14 10*, see tab_loop.xls. 
% The 2 modes from this run are stored in *modesSep14.xls*. 
% 
%
%
% For the names of states and shocks, refer to outputs *STANAMES* and
% *SHONAMES* withing each code. 
%
clear all; close all; cucd=cd; 
% =========================================================================
%% USER SETTINGS 
%
% Unless otherwise explained here, refer to descriptions above 
% =========================================================================

%% A) Files and names 
% =========================================================================
% *Variables that must be defined in the settingsFileName located in
% settings Path*
% 1) addsol 2) solveopt 3) irf_report 4) irf_gnames 5) irf_shocks
% (optional, if empty all)

%% Small 4 Sigals Only 
% settingsPath='O:\PROJ_LIB\LJM\exog\CEFJ\Small\Analysis of Split Model'; 
% modeFileName='secondModeJan10_2012'; 
% outputPath='secondMode';

%% Small 6 Signals 
% settingsPath='O:\PROJ_LIB\LJM\exog\CEFJ\MediumNorm\Kappa Gap levH Prior5'; 
% modeFileName='parMode'; 
% outputPath='twoModes';

%% Big Growth 
settingsPath='O:\PROJ_LIB\LJM\exog\CEFJ\BigARMAHP\Prior9 Gap OverIdent HP FL\02 03 12';
modeFileName='mode'; 
outputPath=[];
sheetName=[]; 

flagUnitImpulse=0; 

legends={'Gap','Growth'}; 
settingsFileName='settingsIRF'; 


modePath=settingsPath; 
add2FunctionHandle='Obs'; 
%% B) Settings for the IMPS 
nirfper=11; 
perturb_name='tau'; 
perturb_grid=[0.05 0.1];  % Loaded value will be included 


%% B) Settings for plots
in.titfont=12; 
in.legfont=12; 
in.flag_legendoff=0; 
in.flag_addpath=1; 
in.addcover={'Chi =1';'Perturbation PSI, estimated 0.75'}; 

% =======================================================================
% ==================== END USER INPUTS ===================================

%% I. Load Settings File 
cd(settingsPath); 
eval(settingsFileName); 

%% II. Load xls file FNAME from sheet sheetname

cd(modePath);
if exist('sheetName','var')==0 || isempty(sheetName)
    [parmodes,parnames]=xlsread(modeFileName);
else
    [parmodes,parnames]=xlsread(modeFileName,sheetName);
end
if size(parmodes,2)==1
    disp('Loaded single parameter value');
    pause(0.2);
    flag_single=1; 
else
    disp('Loaded multiple parameter values');
    pause(0.2);
    flag_single=0; 
end
cd(cucd);
printcell([parnames(:) num2cprec(parmodes)]);  

% =========================================================================
%% III. Automatically Obtain the Model Handle 
funcHandle=settingsPath(findstr(settingsPath,'exog')+5:end); 
delimiters=findstr(funcHandle,'\'); 
if length(delimiters)==1; 
    funcHandle(findstr(funcHandle,'\'))=''; 
else 
    funcHandle=funcHandle(1:delimiters(2)); 
    funcHandle(findstr(funcHandle,'\'))=''; 
end 
funcHandle=['mod',funcHandle]; 

if ~isempty(add2FunctionHandle);
    [junk,junk,maxdif,]=checkmodels_lmj(str2func(funcHandle),str2func([funcHandle,add2FunctionHandle])...
        ,parmodes(:,1),solveopt,addsol);
    if  maxdif > 1e-5;
        error('SOlutions Do not match');
    end
    funcHandle=str2func([funcHandle,add2FunctionHandle]); 
else 
    funcHandle=str2func(funcHandle); 
end 
disp(['Name of model:',func2str(funcHandle)]); 
pause(0.5); 
clear delimiters add2FunctionHandle; 

%% IV. Create Output Path 

outPath=cr_dir(modePath,[outputPath,' ',strdate] ); 

%% V. Check model solves at first column of loaded values 
% Use this to get stanames and ssnames 
[GG, RR, CONS, eu, SDX, ZZ, outfield, ssvec, flag, ssnames, stanames,shockNamesStru]=feval(funcHandle,parmodes(:,1), solveopt, addsol);
shonames=shockNamesStru.long; 
 if ~isequal( eu,[1;1] ) 
     error('Cannot solve model at first column of parmode') 
 end 
 if length(shonames)~=size(SDX,1) 
     error('Wrong dimension of shonames') 
 end 
 if length(stanames)~=size(GG); 
     error('Wrong dimension of stanames')
 end 
 %% Check IRF variables and shock names exist 
 
 % irf_report are the states to be reported
 disp('Check states to be reported exist');
 state_pos=extractlevels(irf_report,stanames);
 
 % irf_shocks are shocks to be reported 
 disp('Check shocks to be reported exist');
 if exist('irf_shocks','var')==0 || isempty(irf_shocks); 
     shocks_pos=(1:size(SDX,1)); 
 else 
     shocks_pos=cellposition(irf_shocks,shonames); 
 end
 
 % irf_report_gnames are the names assigned to the variables
 if exist('irf_report_gnames','var') && ~isempty(irf_report_gnames);
     disp('Will use alternative name for IRFS');
     disp('Original Names      Graph Names');
     if length( irf_report(:)  ) ~= length( irf_report_gnames(:) )
         dispaj('Length IRF_REPORT:',length( irf_report(:)  ) );
         dispaj('Length IRF_REPORT_GNAMES:',length( irf_report_gnames(:)  ) );

         error('Lengths of IRF_REPORT and IRF_REPORT_GNAMES do not match')
     end
     printcell([irf_report(:) irf_report_gnames(:)]);
     pause(1);
     
 end
 
 
%% II. If using a single parameter perturbation, create grid in ascending
%order 

if flag_single
    if ~isempty( perturb_name )
        disp(['Perturbing :',perturb_name]);
        perturb_pos=cellposition(perturb_name,parnames);
        perturb_grid=sort([perturb_grid(:);parmodes(perturb_pos)],'ascend');
        parmodes=repmat(parmodes,[1 (length(perturb_grid))]);
        parmodes(perturb_pos,:)=perturb_grid;
        legends=fnumcell([perturb_name,' '],perturb_grid,3);
        disp('Perturbation values');
        printcell( num2cprec(perturb_grid(:)) );
    else
        display('Perturbname is empty, perturbing a single mode')
        legends={'Mode'}; 
    end
end     

%% III. Solve model for each value of PARMODES, also store SS vector 
nstates=length(ssvec); 
ncols    =size(parmodes,2); 
nirf     =length( irf_report ); 
nx       =size(SDX,1); 

ss_mat=zeros(nstates,ncols); 
irf_mat=zeros(nirf,nirfper,nx,ncols); 
ok_vec=zeros(ncols,1); 

for ii=1:ncols;
    [junk,junk,irfstates,ssvec]=irf_quick(funcHandle,parmodes(:,ii),solveopt,addsol,...
        nirfper,irf_report,0,flagUnitImpulse);
    if ~isempty(irfstates)
        ok_vec(ii)=1;
        irf_mat(:,:,:,ii)=irfstates;
        ss_mat(:,   ii)=ssvec;
    end
end

% Delete those for which could not find a solution 
pos_ok=find(ok_vec==1); 
irf_mat=irf_mat(:,:,:,pos_ok); 
ss_mat =ss_mat(:,pos_ok); 
legends=legends(pos_ok); 
if flagUnitImpulse == 1 
    for kk=1:length(legends); 
        legends(kk)={[legends{kk},' (unit)']}; 
    end 
end 

    

%% IV. Create IRFS, dps file of IRFS 
cd(cucd); 
ghvec=compare_irf_plots(irf_mat,shocks_pos,irf_report_gnames,shonames,legends,outPath,in); 
cd(outPath); 
ps2pdf('psfile', 'IRFs.ps', 'pdffile', 'IRFS.pdf','deletepsfile',1); 
cd(cucd); 

%% V. Create XLS with SS values
cd(outPath); 
sscell=crtcell( ss_mat, ssnames , legends ,{'SS Values'} ); 
parcell=crtcell( parmodes, parnames, fnumcell('Mode',1:size(parmodes,2)) ); 

xlswrite('SS tab',sscell); 
xlswrite('Modes',parcell); 
cd(cucd); 

disp('SS for different modes'); 
printcell(sscell); 

disp('_______________________'); 
disp('COMPARE_IRF complete'); 
display(['Output saved in :',outPath]); 